package com.ch.engine.daily.limit;

import java.time.LocalTime;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 固定窗口算法
 * 因为只计算了时间点的下一个时间窗口，没有连通统计时间点的上一个窗口，所以一定会出现：当遇到时间窗口的临界突变，有可能限流次数就大于配置值了
 *
 * @author wangchunhui
 * @date 2024/12/24 10:30
 */
public class RateLimiterSimpleWindow {
    /**
     * 阈值
     */
    private static final Integer QPS = 2;
    /**
     * 时间窗口（毫秒）
     */
    private static final long TIME_WINDOWS = 1000;
    /**
     * 计数器
     */
    private static final AtomicInteger REQ_COUNT = new AtomicInteger();

    private static long START_TIME = System.currentTimeMillis();

    public synchronized static boolean tryAcquire() {
        if ((System.currentTimeMillis() - START_TIME) > TIME_WINDOWS) {
            REQ_COUNT.set(0);
            START_TIME = System.currentTimeMillis();
        }
        return REQ_COUNT.incrementAndGet() <= QPS;
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 20; i++) {
            Thread.sleep(250);
            LocalTime now = LocalTime.now();
            if (!tryAcquire()) {
                System.out.println(now + " 被限流");
            } else {
                System.out.println(now + " yes");
            }
        }
    }
}